package co.baiku.boot.core.orm.request;

import co.baiku.boot.common.tools.ObjectTools;
import co.baiku.boot.common.tools.StringTools;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

public class RequestFilter {

    public String fieldName;
    public Object value;
    public Operator operator;

    public RequestFilter(String fieldName, Operator operator, Object value) {
        this.fieldName = fieldName;
        this.value = value;
        this.operator = operator;
    }

    /**
     * searchParams中key的格式为OPERATOR_FIELDNAME
     * <p>EQ, LIKE, GT, LT, GTE, LTE</p>
     */
    public static Map<String, RequestFilter> parse(Map<String, Object> searchParams) {
        Map<String, RequestFilter> filters = new HashMap<>();
        if (searchParams == null) {
            searchParams = new HashMap<>();
        }
        for (Entry<String, Object> entry : searchParams.entrySet()) {
            // 过滤掉空值
            String key = entry.getKey();
            Object value = entry.getValue();
            if (ObjectTools.isBlank(value)) {
                continue;
            }
            filters.put(key, of(key, value));
        }
        return filters;
    }

    public static RequestFilter of(String name, Object value) {
        String[] names = name.split(StringTools.UNDERLINE);
        if (names.length != 2 && names.length != 3) {
            throw new IllegalArgumentException(name + " is not a valid search filter name");
        }
        String filedName = names[1];
        Operator operator = Operator.valueOf(names[0]);
        return new RequestFilter(filedName, operator, value);
    }


    public enum Operator {
        EQ, LIKE, LLIKE, RLIKE, GT, LT, GTE, LTE, IN, NIN, NE, ISNULL, ISNOTNULL, OR, AND;

        private static Map<String, Operator> values = new HashMap<>();

        public static Operator of(String name) {
            if (values.isEmpty()) {
                for (Operator value : Operator.values()) {
                    values.put(value.name(), value);
                }
            }
            return values.get(name);
        }
    }
}
